package com.hxw.android.utils;

import com.adb.command.android.app.ActivityCmd;
import com.adb.command.android.app.AndroidAppCmd;
import com.adb.process.ADBCtrl;
import com.adb.process.Device;
import com.adb.process.android.AndroidSystem;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.input.*;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import javafx.stage.FileChooser;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

import java.io.File;
import java.io.IOException;
import java.rmi.activation.Activatable;
import java.util.List;

public class Main extends Application {

    private final Button mFileBtn = new Button("获\r\n取\r\n文\r\n件");
    private final Button mInstallBtn = new Button("安装");
    private final Button mUninstallBtn = new Button("卸载");
    private final Button mStartAPPBtn = new Button("启动应用");

    private final TextField inputTv = new TextField();
    private final TextArea outputTv = new TextArea();

    private String mPackageName = null;

    @Override
    public void start(Stage stage) throws Exception {
        AnchorPane root = new AnchorPane();

        initTv(root);
        initButton(root);

        Scene scene = new Scene(root);
        stage.setScene(scene);
        stage.initStyle(StageStyle.DECORATED);
        stage.setTitle("Android小工具");
        stage.setHeight(600);
        stage.setWidth(800);
        stage.show();
    }

    private void initButton(AnchorPane root) {

        mInstallBtn.setPrefHeight(40);
        mInstallBtn.setPrefWidth(50);
        AnchorPane.setBottomAnchor(mInstallBtn,20.0);
        AnchorPane.setLeftAnchor(mInstallBtn,50.0);

        mUninstallBtn.setPrefHeight(40);
        mUninstallBtn.setPrefWidth(50);
        AnchorPane.setBottomAnchor(mUninstallBtn,20.0);
        AnchorPane.setLeftAnchor(mUninstallBtn,120.0);

        mStartAPPBtn.setPrefHeight(40);
        mStartAPPBtn.setPrefWidth(90);
        AnchorPane.setBottomAnchor(mStartAPPBtn,20.0);
        AnchorPane.setLeftAnchor(mStartAPPBtn,190.0);

        mInstallBtn.setOnMouseClicked(event -> {
            installApk();
        });

        mUninstallBtn.setOnMouseClicked(event -> {
            uninstallApk();
        });

        mStartAPPBtn.setOnMouseClicked(event -> {
            startApk();
        });

        root.getChildren().addAll(mInstallBtn,mUninstallBtn,mStartAPPBtn);
    }

    private void uninstallApk() {
        String path = inputTv.getText();

        if (mPackageName == null||!path.endsWith(".apk")){
            showAlter("卸载失败","未获取到APK或包名");
            return;
        }

        ADBCtrl ctrl = new ADBCtrl();
        Device device = ctrl.firstDevice();
        if (ctrl.firstDevice() == null){
            showAlter("卸载失败","未检测到设备");
        }else{
            try {
                String msg = device.exec(new AndroidAppCmd().uninstall(mPackageName));
                showAlter("卸载结果",msg);
            } catch (IOException e) {
                e.printStackTrace();
                showAlter("卸载异常",e.getMessage());
            }

        }
    }

    private void installApk() {
        String path = inputTv.getText();

        if (mPackageName == null||!path.endsWith(".apk")){
            showAlter("安装失败","未获取到APK或包名");
            return;
        }

        ADBCtrl ctrl = new ADBCtrl();
        Device device = ctrl.firstDevice();
        if (ctrl.firstDevice() == null){
            showAlter("安装失败","未检测到设备");
        }else{
            try {
                String msg = device.exec(new AndroidAppCmd().install(path,true,true));
                showAlter("安装结果",msg);
            } catch (IOException e) {
                e.printStackTrace();
                showAlter("安装结果",e.getMessage());
            }

        }

    }

    private void startApk() {
        String path = inputTv.getText();

        if (mPackageName == null||!path.endsWith(".apk")){
            showAlter("启动失败","未获取到APK或包名");
            return;
        }

        ADBCtrl ctrl = new ADBCtrl();
        Device device = ctrl.firstDevice();
        if (ctrl.firstDevice() == null){
            showAlter("启动失败","未检测到设备");
        }else{
            try {
                String msg = device.exec(new ActivityCmd().startActivity(mPackageName));
                showAlter("启动结果",msg);
            } catch (IOException e) {
                e.printStackTrace();
                showAlter("启动结果",e.getMessage());
            }
        }
    }

    private void analyseAPK() {
        outputTv.clear();
        mPackageName = null;

        String path = inputTv.getText();

        if (path==null||path.isEmpty()){
            outputTv.appendText("\r\n路径不能为空");
            return;
        }

        if (!path.endsWith("apk")){
            outputTv.appendText("\r\n不支持.apk以外的文件");
            return;
        }

        String local = JarUtils.getJarPath(Main.class,"UTF-8");
        if (local == null||local.isEmpty()){
            outputTv.appendText("\r\n获取路径失败"+local);
            return;
        }

        File localFile = new File(local);
        if (!localFile.exists()||!localFile.getParentFile().isDirectory()){
            outputTv.appendText("\r\n获取所在文件夹失败"+local);
            return;
        }

        File apptFile = new File(localFile.getParent()+"\\aapt.exe");
        if (!apptFile.exists()){
            outputTv.appendText("\r\n获取AAPT文件失败"+apptFile);
            return;
        }

        WindowCmdCtrl ctrl = new WindowCmdCtrl();
        ctrl.setCharset("UTF-8");

        //路径前后加双引号，解决路径中可能存在空格的问题
        String cmd = apptFile.getAbsolutePath()+" dump badging "+"\""+path+"\"";

        String result = ctrl.exec(cmd);

        if (result!=null&&!result.contains("package: name")){
            //Window系统的默认编码格式为GBK
            ctrl.setCharset("GBK");

            outputTv.setText("执行命令："+cmd+"\r\n\r\n"+"返回结果："+ctrl.exec(cmd));
        }else{
            outputTv.setText(result);

            mPackageName = result.substring(result.indexOf("'")+1,result.indexOf("' "));//获取包名
        }
    }

    private void initTv(AnchorPane root) {
        inputTv.setPrefHeight(70);

        inputTv.setEditable(false);
        inputTv.setText("可直接把apk文件拉进文本框或点击右侧按钮");

        mFileBtn.setPrefHeight(70);
        mFileBtn.setPrefWidth(50);
        mFileBtn.setOnAction(event -> {
            FileChooser chooser = new FileChooser();
            chooser.setTitle("请选择要打开的文件");
            //筛选文件类型
            chooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("文件类型","*.apk"));

            File file = chooser.showOpenDialog(new Stage());
            //如果不选文件直接关闭窗口的话，返回值为空
            if(file != null){
                inputTv.setText(file.getAbsolutePath());
                analyseAPK();
            }
        });


        AnchorPane.setTopAnchor(mFileBtn,30.0);
        AnchorPane.setRightAnchor(mFileBtn,10.0);

        AnchorPane.setTopAnchor(inputTv,30.0);
        AnchorPane.setRightAnchor(inputTv,70.0);
        AnchorPane.setLeftAnchor(inputTv,10.0);

        //监听文件拖动文本框内
        inputTv.setOnDragExited(event -> {
            List<File> files = event.getDragboard().getFiles();
            if (files!=null&&!files.isEmpty()){
                inputTv.setText(files.get(0).getAbsolutePath());
                analyseAPK();
            }
        });

        outputTv.setWrapText(true);
        outputTv.setPrefHeight(200);
        AnchorPane.setTopAnchor(outputTv,150.0);
        AnchorPane.setRightAnchor(outputTv,10.0);
        AnchorPane.setLeftAnchor(outputTv,10.0);
        AnchorPane.setBottomAnchor(outputTv,70.0);

        outputTv.setOnMouseClicked(event -> {
            if (event.getButton() == MouseButton.SECONDARY) {
                final ClipboardContent content = new ClipboardContent();
                content.putString(outputTv.getText().trim());
                Clipboard.getSystemClipboard().setContent(content);
            }
        });

        root.getChildren().addAll(inputTv,outputTv,mFileBtn);
    }

    private void showAlter(String title,String msg){
        Alert alert = new Alert(Alert.AlertType.INFORMATION);
        alert.setTitle("提示");
        alert.setContentText(msg);
        alert.setHeaderText(title);
        alert.showAndWait();
    }

    public static void main(String[] args) {
        launch();
    }
}
